package com.galaxy.commom.base.utils;

import com.galaxy.commom.base.constant.CommonConstants;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Map;
import lombok.extern.slf4j.Slf4j;


/**
 * http请求GET和 POST工具类
 *
 * @author caijinbang
 */
@Slf4j
public class HttpRequestUtils {

	/**
	 * 默认连接超时时间：毫秒
	 */
	private final static int DEFAULT_CONNECT_TIMEOUT = 6000;

	/**
	 * 默认读取超时时间：毫秒
	 */
	private final static int DEFAULT_READ_TIMEOUT = 12000;

	/**
	 * 内容类型定义
	 */
	public final static String CONTENT_TYPE_DEF = "application/x-www-form-urlencoded";

	/**
	 * 内容json类型
	 */
	public final static String CONTENT_TYPE_JSON = "application/json; charset=utf-8";

	/***************************************************** GET请求 *******************************************************/
	/**
	 * GET请求
	 *
	 * @param url 请求路径
	 * @return 返回数据
	 * @throws IOException io异常
	 */
	public static String readContentFromGet(String url) throws IOException {
		return readContentFromGet(url, DEFAULT_CONNECT_TIMEOUT, DEFAULT_READ_TIMEOUT, null);
	}

	/**
	 * GET请求
	 *
	 * @param url 请求路径
	 * @param connectTimeout 连接超时时间
	 * @param readTimeout 读取超时时间
	 * @return 返回数据
	 * @throws IOException io异常
	 */
	public static String readContentFromGet(String url, int connectTimeout, int readTimeout)
			throws IOException {
		return readContentFromGet(url, connectTimeout, readTimeout, null);
	}

	/**
	 * GET请求，UTF-8编码
	 *
	 * @param url 请求类型
	 * @return 返回数据
	 * @throws IOException io异常
	 */
	public static String readContentFromGetOfUTF8(String url) throws IOException {
		return readContentFromGet(url, DEFAULT_CONNECT_TIMEOUT, DEFAULT_READ_TIMEOUT,
				CommonConstants.UTF8);
	}

	/**
	 * GET请求，UTF-8编码
	 *
	 * @param url 请求路径
	 * @param connectTimeout 连接超时时间
	 * @param readTimeout 读取超时时间
	 * @return 返回数据
	 * @throws IOException io异常
	 */
	public static String readContentFromGetOfUTF8(String url, int connectTimeout, int readTimeout)
			throws IOException {
		return readContentFromGet(url, connectTimeout, readTimeout, CommonConstants.UTF8);
	}

	/**
	 * GET请求，GB2312编码
	 *
	 * @param url 请求路径
	 * @return 返回数据
	 * @throws IOException io异常
	 */
	public static String readContentFromGetOfGB2312(String url) throws IOException {
		return readContentFromGet(url, DEFAULT_CONNECT_TIMEOUT, DEFAULT_READ_TIMEOUT,
				CommonConstants.GB2312);
	}

	/**
	 * GET请求，GB2312编码
	 *
	 * @param url 请求路径
	 * @param connectTimeout 连接超时时间
	 * @param readTimeout 读取超时时间
	 * @return 返回数据
	 * @throws IOException io异常
	 */
	public static String readContentFromGetOfGB2312(String url, int connectTimeout, int readTimeout)
			throws
			IOException {
		return readContentFromGet(url, connectTimeout, readTimeout, CommonConstants.GB2312);
	}

	/**
	 * GET请求
	 *
	 * @param url 请求路径
	 * @param connectTimeout 连接超时时间
	 * @param readTimeout 读取超时时间
	 * @param encode 编码格式
	 * @return 返回数据
	 * @throws IOException io异常
	 */
	public static String readContentFromGet(String url, int connectTimeout, int readTimeout,
			String encode) throws
			IOException {
		URL getUrl = new URL(url);
		// 根据拼凑的URL,打开连接,URL.openConnection()函数会根据URL的类型，返回不同的URLConnection子类的对象,在这里我们的URL是一个http，因此它实际上返回的是HttpURLConnection
		HttpURLConnection connection = (HttpURLConnection) getUrl.openConnection();
		// 建立与服务器的连接，并未发送数据
		connection.setConnectTimeout(connectTimeout);
		connection.setReadTimeout(readTimeout);
		connection.connect();
		// 发送数据到服务器并使用Reader读取返回的数据
		StringBuilder sb = new StringBuilder();
		BufferedReader in;
		if (encode == null) {
			in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
		} else {
			in = new BufferedReader(new InputStreamReader(connection.getInputStream(), encode));
		}
		String line;
		// 读取返回的内容
		while ((line = in.readLine()) != null) {
			sb.append(line);
		}
		in.close();
		// 断开连接
		connection.disconnect();
		return sb.toString();
	}

	/***************************************************** POST请求 *******************************************************/
	/**
	 * POST请求
	 *
	 * @param url 请求路径
	 * @param content 请求参数
	 * @return 返回数据
	 * @throws IOException io异常
	 */
	public static String readContentFromPost(String url, String content) throws IOException {
		return readContentFromPost(url, content, DEFAULT_CONNECT_TIMEOUT, DEFAULT_READ_TIMEOUT, null);
	}

	/**
	 * POST请求
	 *
	 * @param url 请求路径
	 * @param content 请求参数
	 * @param connectTimeout 连接超时时间
	 * @param readTimeout 读取超时时间
	 * @return 返回数据
	 * @throws IOException io异常
	 */
	public static String readContentFromPost(String url, String content, int connectTimeout,
			int readTimeout) throws IOException {
		return readContentFromPost(url, content, connectTimeout, readTimeout, null);
	}

	/**
	 * POST请求,编码gb2312
	 *
	 * @param url 请求路径
	 * @param content 请求参数
	 * @return 返回数据
	 * @throws IOException io异常
	 */
	public static String readContentFromPostOfGB2312(String url, String content) throws IOException {
		return readContentFromPost(url, content, DEFAULT_CONNECT_TIMEOUT, DEFAULT_READ_TIMEOUT,
				CommonConstants.GB2312);
	}

	/**
	 * POST请求,编码gb2312
	 *
	 * @param url 请求路径
	 * @param content 请求参数
	 * @param connectTimeout 连接超时时间
	 * @param readTimeout 读取超时时间
	 * @return 返回数据
	 * @throws IOException io异常
	 */
	public static String readContentFromPostOfGB2312(String url, String content, int connectTimeout,
			int readTimeout) throws IOException {
		return readContentFromPost(url, content, connectTimeout, readTimeout, CommonConstants.GB2312);
	}

	/**
	 * POST请求,编码utf-8
	 *
	 * @param url 请求路径
	 * @param content 请求参数
	 * @return 返回数据
	 * @throws IOException io异常
	 */
	public static String readContentFromPostOfUTF8(String url, String content) throws IOException {
		return readContentFromPost(url, content, DEFAULT_CONNECT_TIMEOUT, DEFAULT_READ_TIMEOUT,
				CommonConstants.UTF8);
	}

	/**
	 * POST请求,设置超时时间
	 *
	 * @param url 请求路径
	 * @param content 请求参数
	 * @param connectTimeout 连接超时时间
	 * @param readTimeout 读取超时时间
	 * @return 返回数据
	 * @throws IOException io异常
	 */
	public static String readContentFromPostOfUTF8(String url, String content, int connectTimeout,
			int readTimeout) throws IOException {
		return readContentFromPost(url, content, connectTimeout, readTimeout, CommonConstants.UTF8);
	}

	/**
	 * POST请求
	 *
	 * @param url 请求路径
	 * @param content 请求参数
	 * @param connectTimeout 连接超时时间
	 * @param readTimeout 读取超时时间
	 * @param encode 编码格式
	 * @return 返回数据
	 * @throws IOException io异常
	 */
	public static String readContentFromPost(String url, String content, int connectTimeout,
			int readTimeout, String encode) throws
			IOException {
		URL postUrl = new URL(url);
		// 打开连接
		HttpURLConnection connection = (HttpURLConnection) postUrl.openConnection();
		// 打开读写属性，默认均为false
		connection.setDoOutput(true);
		connection.setDoInput(true);
		// 设置请求方式，默认为GET
		connection.setRequestMethod("POST");
		// Post 请求不能使用缓存
		connection.setUseCaches(false);
		connection.setInstanceFollowRedirects(true);
		connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded ");
		connection.setConnectTimeout(connectTimeout);
		connection.setReadTimeout(readTimeout);
		DataOutputStream out = new DataOutputStream(connection.getOutputStream());
		out.writeBytes(content);
		out.flush();
		out.close();
		// 发送数据到服务器并使用Reader读取返回的数据
		BufferedReader reader;
		if (encode == null) {
			reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
		} else {
			reader = new BufferedReader(new InputStreamReader(connection.getInputStream(), encode));
		}
		StringBuilder sb = new StringBuilder();
		String line;
		while ((line = reader.readLine()) != null) {
			sb.append(line);
		}
		reader.close();
		// 关闭连接
		connection.disconnect();
		return sb.toString();
	}

	/***************************************************** GET请求 JSON *******************************************************/
	/**
	 * POST请求，post域为json格式
	 * @param url 请求路径
	 * @param content 请求参数
	 * @param headersMap 请求头数据
	 * @return 返回数据
	 * @throws IOException io异常
	 */
	public static String readContentFromPostJson(String url, String content,
			Map<String, String> headersMap) throws IOException {
		return readContentFromPostJson(url, content, headersMap, DEFAULT_CONNECT_TIMEOUT,
				DEFAULT_READ_TIMEOUT);
	}

	/**
	 * POST请求，post域为json格式
	 * @param url 请求路径
	 * @param content 请求参数
	 * @param headersMap 请求头数据
	 * @param connectTimeout 连接超时时间
	 * @param readTimeout 读取超时时间
	 * @return 返回数据
	 * @throws IOException io异常
	 */
	public static String readContentFromPostJson(String url, String content, Map<String, String> headersMap, int connectTimeout, int readTimeout) throws IOException {
		URL postUrl = new URL(url);
		// 打开连接
		HttpURLConnection connection = (HttpURLConnection) postUrl.openConnection();
		connection.setDoOutput(true);
		connection.setDoInput(true);
		connection.setRequestMethod("POST");
		connection.setUseCaches(false);
		connection.setInstanceFollowRedirects(true);
		connection.setRequestProperty("Content-Type", "application/json; charset=utf-8");
		connection.addRequestProperty("Accept-Charset", "UTF-8");
		if (headersMap != null && headersMap.size() > 0) {
			for (Map.Entry<String, String> header : headersMap.entrySet()) {
				connection.addRequestProperty(header.getKey(), header.getValue());
			}
		}
		connection.setConnectTimeout(connectTimeout);
		connection.setReadTimeout(readTimeout);
		// 此处getOutputStream会隐含的进行connect(即：调用connect()方法)。
		PrintWriter out = new PrintWriter(
				new OutputStreamWriter(connection.getOutputStream(), "utf-8"));
		out.println(content);
		out.flush();
		out.close();
		BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
		StringBuilder sb = new StringBuilder();
		String line;
		while ((line = reader.readLine()) != null) {
			sb.append(line);
		}
		reader.close();
		// 关闭连接
		connection.disconnect();
		return sb.toString();
	}

	/**
	 * POST请求，post域为json格式
	 * @param url 请求路径
	 * @param content 请求参数
	 * @return 返回数据
	 * @throws IOException io异常
	 */
	public static String readContentFromPostJson(String url, String content) throws IOException {
		return readContentFromPostJson(url, content, DEFAULT_CONNECT_TIMEOUT, DEFAULT_READ_TIMEOUT);
	}

	/**
	 * POST请求，post域为json格式
	 * @param url 请求路径
	 * @param content 请求参数
	 * @param connectTimeout 连接超时时间
	 * @param readTimeout 读取超时时间
	 * @return 返回数据
	 * @throws IOException io异常
	 */
	public static String readContentFromPostJson(String url, String content, int connectTimeout, int readTimeout) throws IOException {
		URL postUrl = new URL(url);
		// 打开连接
		HttpURLConnection connection = (HttpURLConnection) postUrl.openConnection();
		connection.setDoOutput(true);
		connection.setDoInput(true);
		connection.setRequestMethod("POST");
		connection.setUseCaches(false);
		connection.setInstanceFollowRedirects(true);
		connection.setRequestProperty("Content-Type", "application/json; charset=utf-8");
		connection.addRequestProperty("Accept-Charset", "UTF-8");
		connection.setConnectTimeout(connectTimeout);
		connection.setReadTimeout(readTimeout);
		PrintWriter out = new PrintWriter(
				new OutputStreamWriter(connection.getOutputStream(), "utf-8"));
		out.println(content);
		out.flush();
		out.close();
		BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
		StringBuilder sb = new StringBuilder();
		String line;
		while ((line = reader.readLine()) != null) {
			sb.append(line);
		}
		reader.close();
		// 关闭连接
		connection.disconnect();
		return sb.toString();
	}
}